fix(project-management): address a project by its id, not its name (#1363) - #1377
Merged
Victor-w-Madeira merged 1 commit intoAug 8, 2026
Merged
Conversation
…1363) Upstream 23f91d8587 ("fix(authz): support scoped project visibility", #14429) re-keyed the home sidebar's testids from the project NAME to its ID, on the release-1.12.0 line the nightly is cut from: sidebar-nav-${item.name} -> sidebar-nav-${item.id} more-options-button_${convertTestName(item.name)} -> more-options-button_${item.id} Seven @stable tests across four specs hard-failed on the 2026-08-07 daily and were quarantined at triage. This lifts that quarantine. Verdict: an internal rename of an automation hook, not a product regression. Measured live on 1.12.0.dev20 — the name is still the entry's text and the kebab's accessible name (aria-label="Options for <name>"), so nothing a user or a screen reader observes was lost, and no REGRESSIONS.md row is owed. The entry is not gated away by the ProjectRenamePermission wrapper the same commit adds: it always renders its child, canRename only guards onDoubleClick. Addressing now lives in one place, helpers/ui/project-sidebar.ts, matching BOTH spellings as a single locator. Not a hedge: main still renders the name-derived testid and manual.yml dispatches the @stable set against 1.11.x release candidates before every sign-off, so pinning the id alone would trade seven tests red on the nightly for seven red on the lane that signs releases off. The two can never both match — an entry carries exactly one testid, and a project's name is never another project's uuid. The name branch carries its deletion trigger. Second defect, riding on the first: cleanOldFolders drove the kebab through the name-derived testid, so it had been deleting NOTHING and merely timing out on a click — the mechanism behind the New Project -> New Project (5) accumulation the daily's retries recorded inside one test. It now sweeps through the REST API, because it is teardown of the PREVIOUS run and must not depend on the UI state the test it precedes is about to assert on (the argument removeLeftoverRenamedProject already makes in the same file). Measured: 3 seeded New Project* projects, 0 survived. The rename assertion had to change observable. The id-derived testid does not change with a rename, so asserting on it would pass whether the rename committed or not; the entry's TEXT is asserted instead. Also fixed: the two specs carrying the same addressing that were latently broken and invisible to the daily for want of @stable (folder-drag-drop-flow, flow-navigation-between-folders), and the @destructive loop's isVisible() fallback, which could delete a folder other than the one it had just hovered. Unit-covered: the selector builders (both spellings, exact matching, escaping) and the cleanup sweep.
Contributor
There was a problem hiding this comment.
Pull request overview
Updates the e2e suite’s project-sidebar addressing to be resilient to upstream Langflow changing data-testid keys from project name → project id (release-1.12.0 line), restoring quarantined @stable coverage and hardening cleanup.
Changes:
- Introduce a shared
ProjectRef-based sidebar locator helper that matches both id- and name-derived testid spellings. - Refactor affected specs +
MainPagehelpers to address projects via{ id, name }instead of name-only selectors; restore@stableand removetest.fixme. - Move
cleanOldFoldersfrom UI-driven deletion to REST API deletion and add unit coverage for the new selector/cleanup behaviors.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/tests-automations/regression/mcp/server/mcp-server-starter-projects.spec.ts | Unquarantines the spec and switches folder CRUD interactions to id/name-aware sidebar helpers. |
| tests/tests-automations/regression/core-functionality/project-management/folder-drag-drop-flow.spec.ts | Uses projectSidebarEntry with { id, name } to find/click the folder reliably. |
| tests/tests-automations/regression/core-functionality/project-management/folder-deletion-integrity.spec.ts | Restores @stable tests and replaces name-derived sidebar/kebab selectors with shared helpers. |
| tests/tests-automations/regression/core-functionality/project-management/folder-crud.spec.ts | Refactors create/rename/delete assertions to use ProjectRef and text-based rename verification. |
| tests/tests-automations/regression/core-functionality/project-management/flow-navigation-between-folders.spec.ts | Updates sidebar addressing for both folders to use { id, name } refs. |
| tests/tests-automations/regression/core-functionality/project-management/bulk-actions.spec.ts | Switches sidebar click to the id/name-aware entry locator and restores @stable. |
| tests/pages/MainPage.ts | Changes project helpers (deleteProject, clickProject, uploadFlowByDragDrop) to accept ProjectRef. |
| tests/helpers/ui/project-sidebar.ts | Adds centralized selector builders + locators + openProjectOptions supporting both upstream spellings. |
| tests/helpers/ui/project-sidebar.test.ts | Adds unit tests validating selector matching semantics (id vs name/slug, exactness, escaping). |
| tests/helpers/flows/create-project-through-sidebar.ts | Returns ProjectRef and updates rename helper to return the renamed ProjectRef with a stronger observable. |
| tests/helpers/filesystem/clean-old-folders.ts | Reworks cleanup to delete New Project* folders via REST API (id-scoped) instead of sidebar UI. |
| tests/helpers/filesystem/clean-old-folders.test.ts | Adds unit tests for the API-based cleanup behavior and safety properties. |
| docs/mcp/server/mcp-server-starter-projects.md | Documents the new sidebar addressing helper and updates validation metadata. |
| docs/core-functionality/project-management/folder-deletion-integrity.md | Updates spec doc steps/dependencies to reflect id/name-aware sidebar addressing. |
| docs/core-functionality/project-management/folder-crud.md | Updates rename observable and external dependency notes for the new addressing scheme. |
| docs/core-functionality/project-management/flow-navigation-between-folders.md | Updates validation/dependency text to reflect the new project-sidebar addressing. |
| docs/core-functionality/project-management/bulk-actions.md | Updates validation metadata and sidebar addressing dependency description. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Victor-w-Madeira
deleted the
fix/issue-1363-project-sidebar-addressed-by-id
branch
August 8, 2026 07:03
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1363.
Problem
Seven
@stabletests across four specs hard-failed on the 2026-08-07 daily (run 31163810520) with one shape: a project the backend confirms exists (POST /api/v1/projects→201) never resolves in the home sidebar. Every one failed on all three attempts, across both shards and worker indices 2–17, outside the run's 108 s outage window — so not environmental. They were quarantined manually at triage (@stableremoved andtest.fixmeadded).Upstream
23f91d8587(fix(authz): support scoped project visibility, langflow-ai/langflow#14429) re-keyed both testids from the project name to its id, on therelease-1.12.0line the nightly is cut from:Verdict: internal rename of an automation hook — NOT a product regression
Read from the live DOM on
1.12.0.dev20, not inferred from the commit:The name is still the entry's text and the kebab's accessible name, so nothing a user or a screen reader perceives was lost —
data-testidis a test hook, not a product contract. Keying on the id is also the more correct choice under the change that introduced it: visibility is now per-principal, and a project name is not unique across principals while its id is. NoREGRESSIONS.mdrow is owed and no upstream ticket is filed. Full reasoning recorded on the issue.Ruled out rather than assumed: the
ProjectRenamePermissionwrapper the same commit adds ischildren(can(projectId, "write"))— it always renders its child, andcanRenameonly guardsonDoubleClick. Both projects render live.Fix
Addressing lives in one place —
tests/helpers/ui/project-sidebar.ts— matching both spellings as a single locator.That is not a hedge.
mainstill renders the name-derived testid, andmanual.ymldispatches the@stableset against1.11.xrelease candidates before every sign-off — pinning the id alone would trade seven tests red on the nightly for seven red on the lane that signs releases off. The two branches can never both match: an entry carries exactly one testid, and a project's name is never another project's uuid. The name branch carries its own deletion trigger, and it is the only place that spells it.Rejected: editing each spec in place. The issue's own directive puts the fix in the shared layer, and addressing by the id the create response already returns removes the #1023 ambiguity instead of trading one name for another.
Consumers updated:
MainPage(deleteProject/clickProject/uploadFlowByDragDrop),createProjectThroughSidebar/renameProjectThroughSidebar,cleanOldFolders, the four quarantined specs, and the two latent ones.Second defect, riding on the first
cleanOldFoldersdrove the kebab through the name-derived testid, so fromdev20on it deleted nothing and merely timed out on a click — the mechanism behind theNew Project→New Project (5)accumulation the daily's retries recorded inside a single test. It now sweeps through the REST API: this is teardown of the previous run and must not depend on the UI state the test it precedes is about to assert on, the argumentremoveLeftoverRenamedProjectalready makes in the same file.Measured on
1.12.0.dev20: 3New Project*projects seeded viaPOST /api/v1/projects/, spec run once — 0 of 3 survived.One observable had to change
The id-derived testid does not change with a rename, so asserting on it would pass whether the rename committed or not.
renameProjectThroughSidebarnow asserts the entry's text, and returns the project under its new name (which is what later assertions must address it by on1.11.x, where the testid does change).Scope notes
test.fixmeremoved and@stablerestored.@stable, hence latently broken and invisible to the daily, are fixed here as the issue requires:folder-drag-drop-flow.spec.ts,flow-navigation-between-folders.spec.ts.@destructiveloop kept its assertions; itsisVisible()fallback tomore-options-button_*.first()is gone — it could delete a folder other than the one it had just hovered. The#1008known-defect declaration still fires.mcp-server-starter-projectsleaks one flow and one project per run, masked by the next run'scleanOldFolders. A cleanup defect, not an addressing one.Covered tests
creates, renames and deletes an empty project folder via the UIProject deleted successfully; entry gonedeleting a folder that contains a flow removes the flow with itGET /api/v1/flows/{id}→ 404deleting a folder should update the folder list immediatelyadd-project-buttonstill functionaldeleting one folder should not affect other foldersmainpage_titlerenderscreating a new folder after deletion should work correctlydeleting every folder lands on the empty project screen(@destructive)folderCount === 0, sidebar empty message,new_project_btn_empty_page; the#1008422still fires as declareduser should be able to select flows … bulk actionsuser must be able to see starter projects for mcp serverslf-starter_projectcount 1;lf-new_project/lf-new_project_1appear;lf-renamed_projectappears then count 0 after deletenavigating between two folders scopes the listing to each folder's flowstoHaveCount(0)of flow B, and vice versafolder listing shows flows correctly via UIUnit coverage (
npm run test:units)project-sidebar.test.tsasserts by selection, not string equality — each case compiles the selector and runs it against adata-testid: it matches the id spelling (nightly) and the name spelling (main/1.11.x); the kebab matches the id and the slugified name and not the raw one; matching is exact, soNew Projectdoes not matchNew Project (3); a name carrying"or\still yields a well-formed selector.clean-old-folders.test.tspins the sweep's end state, not its calls: it deletes everyNew Project*and nothing else, deletes by id and never through the sidebar, reads both response shapes, does not throw on a failed list, does not abort on one undeletable leftover, and does not sweep a name that merely contains "New Project".Validation (nightly
1.12.0.dev20,--workers=1 --retries=0)npm run typecheck✅ ·npm run lint✅ (0 errors) ·npm run test:units✅ 531/531 ·npm run test:scripts✅ 795/79511 passedeach (~39 s);@destructivegreen isolated (1 passed)--trace=on✅ — ran normally (23 s), no sign of the Simple Agent-family hang🚨 Backend Errorattributable to this change. Two advisory entries appear, both frommcp-server-starter-projectstest 2, which this PR does not touch and which reproduces them onmain: the409 Server already exists.is that test's own assertion, and the intermittent500onDELETE /api/v1/flows/issqlite3.OperationalError: database is lockedin the cascade delete — the already-filed [Daily #962] api-folders DELETE returns 500 instead of 204 (recurrent) #965/LE-2020 contention class, read from the container's traceback.GET /api/v1/flows/?get_all=trueandGET /api/v1/projects/before and after a clean run — 0 delta for all fiveproject-managementspecs. The+1/+1on the MCP spec is pre-existing and filed as mcp-server-starter-projects leaks one flow and one project per run, hidden by the next run's cleanup #1376.Force-fail — executed, one mutation per test in scope
516,517,520failed — the1.11.xhalf is guarded, not decorativecleanOldFoldersfilter matches nothing109,110,111,113failedrenameProjectThroughSidebarstops filling the input (no rename happens)toContainText; tests 2 and 3, which do not rename, passed — this is what proves the new observable detects a rename that did not commitflow.folder_idandnumberOfErrors@destructivekebab pointed at a non-existent idTimeoutError: locator.click. It needed its own mutation: A does not break it, because it derives the suffix from the DOM and is therefore spelling-agnostic by constructionRevert proven:
grep FF_MUTATIONovertests/returns 0, followed by a final green run.Dependencies
None — pure UI plus REST. No LLM, no provider key. Parallel-safe: every test addresses only projects it created, and cleanup is id-scoped.
🤖 Generated with Claude Code